package com.liyunhan.StrassenAlgorithm;

/**
 * @Description: 实现任意阶方阵乘法
 * 对于任意阶(主要是奇数阶的矩阵)而言，是无法直接使用Strassen算法的，我们可以手动将矩阵的阶数补位1阶到偶数阶。
 * 添加一行一列的全零元素，不会影响计算结果，然后则交由偶数阶Strassen算法完成计算，最后在合并结果矩阵时，
 * 再去掉该阶即可，这样就实现了奇数阶的矩阵乘法，也就实现了任意阶的矩阵乘法。
 * @Author: Liyunhan
 * @Date: 2021/11/16 21:44
 */
public class OptimStrassen2 extends OptimStrassen {
    //如下两个矩阵完成扩增矩阵阶操作
    private double[][] matrixA;
    private double[][] matrixB;

    public OptimStrassen2(int n, double[][] matrix1, double[][] matrix2) {
        super(n, matrix1, matrix2);
    }

    /**
     * 对矩阵进行预处理, 使奇数阶矩阵变为偶数阶
     * @return
     */
    public double prprocessing() {
        double time;
        if (this.getN() % 2 != 0) {
            int n = this.getN();
            //实例化两个用于扩增操作的矩阵
            matrixA = new double[n + 1][n + 1];
            matrixB = new double[n + 1][n + 1];
            //初始化两个矩阵
            initMatrix(n+1, matrixA);
            initMatrix(n+1, matrixB);
            //赋值
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    matrixA[i][j] = this.getMatrix1()[i][j];
                    matrixB[i][j] = this.getMatrix2()[i][j];
                }
            }
            this.setMatrix1(matrixA);
            this.setMatrix1(matrixB);
            //转换为偶数阶后, 调用偶数阶的Strassen算法即可
            return this.start();
        }else {
            //本身就是偶数阶, 直接调用偶数阶的Strassen算法
            return this.start();
        }
    }

    /**
     * 初始化矩阵通用函数
     *
     * @param n
     * @param matrix
     */
    public void initMatrix(int n, double[][] matrix) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                matrix[i][j] = 0.0;
            }
        }
    }
}
